package com.example.demospringmybatisplus.soTokenController;

import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import cn.dev33.satoken.stp.SaLoginModel;
import cn.dev33.satoken.stp.SaTokenInfo;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.util.SaResult;

/**
 * Sa-Token 前后端分离模式示例
 *
 * @author huahua
 * @DATE 2024/9/22
 **/
@RestController
@RequestMapping("/NotCookie/")
public class NotCookieController {
    /**
     * 前后端分离（无Cookie模式）
     *
     * 1、后端将 token 返回到前端
     * 首先调用 StpUtil.login(id) 进行登录。
     * 调用 StpUtil.getTokenInfo() 返回当前会话的 token 详细参数。
     * 此方法返回一个对象，其有两个关键属性：tokenName和tokenValue（token 的名称和 token 的值）。
     * 将此对象传递到前台，让前端人员将这两个值保存到本地。
     *
     * 2、前端将 token 提交到后端
     * 无论是app还是小程序，其传递方式都大同小异。
     * 那就是，将 token 塞到请求header里 ，格式为：{tokenName: tokenValue}。
     */
    @Resource
    private JdbcTemplate jdbcTemplate;

    // 前后端一体模式的登录样例    ---- http://localhost:8086/user/doLogin?username=lisi&password=lisi
    @RequestMapping("doLogin")
    public SaResult doLogin(String username, String password) {
        List<Map<String, Object>> list =
                jdbcTemplate.queryForList("select user_id from users where user_name = ? and password = ?", username, password);
        if (list.isEmpty()) {
            return SaResult.error("用户名或密码错误");
        } else {
            // StpUtil.login(list.get(0).get("user_id"));
            // 指定token有效期(单位: 秒)，如下所示token七天有效
            StpUtil.login(list.get(0).get("user_id"), new SaLoginModel().setTimeout(60 * 60 * 24 * 7));
            return SaResult.ok("登录成功");
        }
    }

    // 前后端分离模式的登录样例    ---- http://localhost:8086/NotCookie/doLogin2?name=zhang&pwd=123456
    @RequestMapping("doLogin2")
    public SaResult doLogin2(String username, String password) {
        List<Map<String, Object>> list =
                jdbcTemplate.queryForList("select user_id from users where user_name = ? and password = ?", username, password);
        if (!list.isEmpty()) {
            // 会话登录
            // StpUtil.login(list.get(0).get("user_id"));
            // `SaLoginModel`为登录参数Model，其有诸多参数决定登录时的各种逻辑，例如：
            StpUtil.login(10001, new SaLoginModel()
                    .setDevice("PC")                // 此次登录的客户端设备类型, 用于[同端互斥登录]时指定此次登录的设备类型
                    .setIsLastingCookie(true)        // 是否为持久Cookie（临时Cookie在浏览器关闭时会自动删除，持久Cookie在重新打开后依然存在）
                    .setTimeout(60 * 60 * 24 * 7)    // 指定此次登录token的有效期, 单位:秒 （如未指定，自动取全局配置的 timeout 值）
                    .setToken("xxxx-xxxx-xxxx-xxxx") // 预定此次登录的生成的Token
                    .setIsWriteHeader(false)         // 是否在登录后将 Token 写入到响应头
            );
            // 与常规登录不同点之处：这里需要把 Token 信息从响应体中返回到前端
            SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
            return SaResult.data(tokenInfo);
        }
        return SaResult.error("登录失败");
    }
}
